package com.witherest.server.common.bean;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 시스템에서 사용하는 properties 파일의 내용을 공 유 메모리로 관리
 * 
 * InitConfigProperties클래스로 선언된 스프링 빈이 WAS 기동시 service.properties 내용의 값을 메모리로 로드 된다.
 * 시스템에서 참조시 ConfigProperties.getXXX(메세지 키)메서드를 리턴
 * 타입에 맞게 호출 하면 된다.
 *
 */
public class RESTfulLoggingInterceptor extends HandlerInterceptorAdapter {

	// ~ Static fields/initializers =====================================================================================

	/** 클래스에서 사용하는 로거. */
	private static final Logger logger = LoggerFactory.getLogger(RESTfulLoggingInterceptor.class);

	// ~ Instance fields ================================================================================================
	// ~ Constructors ===================================================================================================
	// ~ Implementation Method (interface/abstract) =====================================================================
	// ~ Self Methods ===================================================================================================

	/**
	 * AOP Target 메서드 후 실행
	 * 
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#postHandle(javax.servlet.http.HttpServletRequest,
	 * javax.servlet.http.HttpServletResponse, Object, org.springframework.web.servlet.ModelAndView)
	 */
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
			throws Exception {
		super.postHandle(request, response, handler, modelAndView);
	}

	/**
	 * AOP Target 메서드 전 실행
	 * 
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest,
	 * javax.servlet.http.HttpServletResponse, Object)
	 */
	@SuppressWarnings("unchecked")
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		StringBuffer sbAppender = new StringBuffer();
		
		if (logger.isInfoEnabled()) {
			request.setAttribute("WEB_EXECUTE_TIME", new Long(System.currentTimeMillis()));			
			
			sbAppender.append("\n[Request Information (Device => Platform)]\n")
					.append(" Request URL : [" + request.getRequestURI() + "]\n")
					.append(" Client Addr : [" + request.getRemoteHost() + "(IP:" + request.getRemoteAddr() + ")" + "]\n")
					.append(" Request Encoding : [" + request.getCharacterEncoding() + "]\n")
					.append(" Client Info : ").append(request.getHeader("Client-Info")).append("\n")
                    .append(" Token : ").append(request.getHeader("token")).append("\n");
			
				sbAppender.append(" Request Parameters : [");
				Enumeration<String> e = request.getParameterNames();
				while (e.hasMoreElements()) {
					String strKey = e.nextElement();
					String strValues = request.getParameter(strKey);
					sbAppender.append(strKey + "=").append(strValues).append(",");
				}
				sbAppender.append("]\n");
			
			if (logger.isInfoEnabled()) {
				logger.info(sbAppender.toString());
			}
		}
		return super.preHandle(request, response, handler);
	}

	/**
	 * AOP Target 메서드가 성공적으로 처리 된 후 실행
	 * 
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterCompletion(javax.servlet.http.HttpServletRequest,
	 * javax.servlet.http.HttpServletResponse, Object, Exception)
	 */
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		StringBuffer sbAppender = new StringBuffer();
		if (logger.isInfoEnabled()) {
			sbAppender.append("\n Controller Execution time : ["
					+ (System.currentTimeMillis() - ((Long) request.getAttribute("WEB_EXECUTE_TIME")).longValue()) + " ms]\n");

			if (logger.isInfoEnabled()) {
				logger.info(sbAppender.toString());
			}
		}
		super.afterCompletion(request, response, handler, ex);
	}

	// ~ Getter and Setter ==============================================================================================

}
